package com.youlai.boot.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.youlai.boot.common.exception.BusinessException;
import com.youlai.boot.system.enums.RecycleStatusEnum;
import com.youlai.boot.system.enums.RoleTypeEnum;
import com.youlai.boot.system.mapper.*;
import com.youlai.boot.system.model.dto.AuditRequestDTO;
import com.youlai.boot.system.model.entity.*;
import com.youlai.boot.system.model.vo.CalculatePriceVO;
import com.youlai.boot.system.model.vo.TaskAssignmentVO;
import com.youlai.boot.system.service.TaskAssignmentService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author 张雨润
 * @date 2025/2/25 22:03
 * @Description
 */
@Service
@RequiredArgsConstructor
public class TaskAssignmentServiceImpl extends ServiceImpl<TaskAssignmentMapper, TaskAssignment>
        implements TaskAssignmentService {
    private final RecycleRequestMapper recycleRequestMapper;

    private final RequestWasteMapper requestWasteMapper;

    private final TaskAssignmentMapper taskAssignmentMapper;

    private final OrgMapper orgMapper;

    private final UserMapper userMapper;

    private final TransactionMapper transactionMapper;
    private final UserRoleMapper userRoleMapper;
    private final RoleMapper roleMapper;

    private final WasteTypeMapper wasteTypeMapper;
    private final WasteTypeServiceImpl wasteTypeServiceImpl;

    /**
     * 查询配送员任务列表
     * 
     * @param courierId
     * @return
     */
    @Override
    public List<TaskAssignmentVO> getCourierTaskList(Long courierId) {
        if (courierId != null) {
            List<TaskAssignment> taskList = new LambdaQueryChainWrapper<>(taskAssignmentMapper)
                    .eq(TaskAssignment::getCourierId, courierId)
                    .orderByDesc(TaskAssignment::getUpdateTime)
                    .list();
            if (CollUtil.isEmpty(taskList)) {
                return List.of();
            }
            return taskList.parallelStream().map(item -> {
                TaskAssignmentVO vo = new TaskAssignmentVO();
                taskToVO(item, vo);
                return vo;
            }).toList();
        }
        return List.of();
    }

    /**
     * 获取指定配送员任务
     * 
     * @param taskId
     * @return
     */
    @Override
    public TaskAssignmentVO getCourierTask(Long taskId) {
        TaskAssignmentVO vo = new TaskAssignmentVO();
        if (taskId != null) {
            TaskAssignment taskAssignment = taskAssignmentMapper.selectById(taskId);
            taskToVO(taskAssignment, vo);
        }
        return vo;

    }

    // 实体-->VO
    private void taskToVO(TaskAssignment taskAssignment, TaskAssignmentVO vo) {
        if (taskAssignment == null) {
            return;
        }
        BeanUtil.copyProperties(taskAssignment, vo);
        // 回收机构名称
        if (taskAssignment.getOrgId() != null) {
            vo.setOrgName(orgMapper.selectById(taskAssignment.getOrgId()).getOrgName());
        }
        RecycleRequest recycleRequest = recycleRequestMapper.selectById(taskAssignment.getRequestId());
        if (recycleRequest == null) {
            return;
        }

        vo.setUserId(recycleRequest.getUserId());
        if (recycleRequest.getUserId() != null) {
            vo.setUsername(userMapper.selectById(recycleRequest.getUserId()).getUsername());
        }
        vo.setMobile(recycleRequest.getMobile());
        vo.setRecycleTime(recycleRequest.getRecycleTime());
        vo.setArea(List.of(recycleRequest.getProvince(), recycleRequest.getCity(), recycleRequest.getCountry()));
        vo.setAddress(recycleRequest.getAddress());
        vo.setStatus(recycleRequest.getStatus());
        vo.setRejectReason(recycleRequest.getRejectReason());
        vo.setWasteList(new LambdaQueryChainWrapper<>(requestWasteMapper)
                .eq(RequestWaste::getRequestId, taskAssignment.getRequestId()).list());
    }

    /**
     * 配送员确认回收垃圾
     * 
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean auditAssignTask(AuditRequestDTO dto) {
        // 1.更新请求主表状态
        RecycleRequest recycleRequest = recycleRequestMapper.selectById(dto.getRequestId());
        TaskAssignment taskAssignment = taskAssignmentMapper.selectById(dto.getTaskId());
        // 键为id，值为本身
        Map<Long, WasteType> wasteTypeMap = wasteTypeMapper.selectList(null).stream()
                .collect(Collectors.toMap(WasteType::getId, wasteType -> wasteType));
        if (dto.getAuditStatus() == 0) {// 通过
            recycleRequest.setStatus(RecycleStatusEnum.RECYCLING.getCode());
            // 新增垃圾列表
            dto.getWasteList().forEach(rw -> {
                // 计算收益价格
                RequestWaste requestWaste = RequestWaste.builder()
                        .requestId(recycleRequest.getId())
                        .fileUrl(rw.getFileUrl())
                        .typeId(rw.getTypeId())
                        .weight(rw.getWeight())
                        .actualPrice(rw.getActualPrice())
                        .build();

                requestWasteMapper.insert(requestWaste);
            });
            recycleRequest.setExpectReturn(dto.getExpectReturn());

            // 2. 修改配送任务状态为已经上门回收
            taskAssignment.setIsReceived(1);
            taskAssignmentMapper.updateById(taskAssignment);
        } else {// 驳回
            recycleRequest.setStatus(RecycleStatusEnum.REJECTED.getCode());
            recycleRequest.setRejectReason(dto.getRejectReason());
        }
        recycleRequest.setUpdateTime(LocalDateTime.now());
        recycleRequestMapper.updateById(recycleRequest);

        // 2.更新任务表
        taskAssignment.setCompletedTime(LocalDateTime.now());
        taskAssignmentMapper.updateById(taskAssignment);
        return true;
    }

    /**
     * 一键计算收益
     * 
     * @param wasteList
     * @return <typeId,actualPrice>
     */
    @Override
    public CalculatePriceVO calculatePrice(List<RequestWaste> wasteList) {
        if (wasteList == null || wasteList.isEmpty()) {
            return new CalculatePriceVO();
        }

        CalculatePriceVO vo = new CalculatePriceVO();
        Map<Long, BigDecimal> priceMap = new HashMap<>();
        BigDecimal totalPrice = BigDecimal.ZERO;

        // 获取废品类型映射，增加空指针检查
        List<WasteType> wasteTypes = Optional.ofNullable(wasteTypeMapper.selectList(null))
                .orElse(Collections.emptyList());
        Map<Long, WasteType> wasteMap = wasteTypes.stream()
                .collect(Collectors.toMap(WasteType::getId, wasteType -> wasteType));

        // 依次计算收益并收集为map
        for (RequestWaste rw : wasteList) {
            Long typeId = rw.getTypeId();
            if (typeId == null) {
                continue; // 跳过无效的废品类型
            }

            WasteType wasteType = wasteMap.get(typeId);
            if (wasteType == null) {
                continue; // 跳过无效的废品类型
            }

            BigDecimal weight = Optional.ofNullable(rw.getWeight()).orElse(BigDecimal.ZERO);
            try {
                // 计算收益
                BigDecimal actualPrice = wasteTypeServiceImpl
                        .calculateUserRevenue(weight.multiply(new BigDecimal("0.001")), wasteType);
                totalPrice = totalPrice.add(actualPrice);
                priceMap.put(typeId, actualPrice);
            } catch (Exception e) {
                throw new BusinessException("计算收益失败");
            }
        }

        vo.setPriceMap(priceMap);
        vo.setTotalPrice(totalPrice);
        return vo;
    }

}
